package util

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"gitee.com/sky_big/workmod/myLog"
	"github.com/gogf/gf/g/os/glog"
	"math"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"
)

// CHK: 校验和，数据域数据的累加和 （1 字节）
func Check(data []byte) byte {
	var sum byte = 0
	for i := 0; i < len(data); i++ {
		sum += data[i]
	}
	return sum
}

//byte转16进制字符串
func ByteToHex(data []byte) string {
	buffer := new(bytes.Buffer)
	for _, b := range data {
		s := strconv.FormatInt(int64(b&0xff), 16)
		if len(s) == 1 {
			buffer.WriteString("0")
		}
		buffer.WriteString(s)
	}
	return strings.ToUpper(buffer.String())
}

//16进制字符串转[]byte
func HexToByte(hex string) []byte {
	// 去除空格
	hex = strings.Replace(hex, " ", "", -1)
	length := len(hex) / 2
	slice := make([]byte, length)
	rs := []rune(hex)

	for i := 0; i < length; i++ {
		s := string(rs[i*2: i*2+2])
		value, _ := strconv.ParseInt(s, 16, 10)
		slice[i] = byte(value & 0xFF)
	}
	return slice
}

//2字节转换成整型
func BytesToUInt16(b []byte) int {
	bytesBuffer := bytes.NewBuffer(b)

	var x uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &x)

	return int(x)
}

//4字节转换成整型
func BytesToUInt32(b []byte) int {
	bytesBuffer := bytes.NewBuffer(b)

	var x uint32
	binary.Read(bytesBuffer, binary.LittleEndian, &x)

	return int(x)
}

//整型转换成字节
func Int16ToBytes(n int) []byte {
	x := uint16(n)

	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.LittleEndian, x)
	return bytesBuffer.Bytes()
}

//BCD码转表地址
func ByteToAddr(data []byte) string {
	buffer := new(bytes.Buffer)
	for i := len(data) - 1; i >= 0; i-- {
		s := strconv.FormatInt(int64(data[i]&0xff), 16)
		if len(s) == 1 {
			buffer.WriteString("0")
		}
		buffer.WriteString(s)
	}
	return buffer.String()
}

//BCD码转表当前读数
func ByteToMeterValue(data []byte) float64{
	var x int
	for i := len(data) - 1; i >= 0; i-- {
		b := data[i]
		//高四位
		b1 := (byte)((b >> 4) & 0xF)
		//低四位
		b2 := (byte)(b & 0xF)
		x += int(b1*10+b2) * int(math.Pow10(2*i))
	}

	return float64(x) / 10
}

func BCDToInt(data []byte) int {
	var x int
	for i := len(data) - 1; i >= 0; i-- {
		b := data[i]
		//高四位
		b1 := (byte)((b >> 4) & 0xF)
		//低四位
		b2 := (byte)(b & 0xF)
		x += int(b1*10+b2) * int(math.Pow10(2*i))
	}

	return x
}

func FloatToString(inputNum float64) string {
	// to convert a float number to a string
	return strconv.FormatFloat(inputNum, 'g', 6, 64)
}
//打印内容到文件中
func TraceFile(strContent string) {
	os.Mkdir("log", os.ModePerm)
	fdTime := time.Now().Format("2006-01-02 15")
	fd, _ := os.OpenFile("log/"+fdTime+".txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	fdTime = time.Now().Format("15:04:05")
	fdContent := strings.Join([]string{"======", fdTime, "=====\n", strContent, "\n"}, "")
	buf := []byte(fdContent)
	fd.Write(buf)
	fd.Close()
}
//格式化时间
func FormatTime(bytes []byte) string {
	//format:="Y-m-d H:i:s"
	formatArr := []string{
		"", "-", "-", " ", ":", ":", "",
	}
	var str string
	if len(bytes) > len(formatArr) {
		glog.Error("Format Time str is not right", bytes)
		return str
	}
	for i := 0; i < len(bytes); i++ {
		s := hex.EncodeToString([]byte{bytes[i]})
		str = str + s + formatArr[i]
	}
	fmt.Println("str=============", str)
	return str
}

// 保护方式允许一个函数
func ProtectRun(entry func()) {
	// 延迟处理的函数
	defer func() {
		// 发生宕机时，获取panic传递的上下文并打印
		err := recover()
		if err!=nil{
			switch err.(type) {
			case runtime.Error: // 运行时错误
				myLog.Error("runtime error:", err)
			default: // 非运行时错误
				myLog.Error("error:", err)
			}
		}
	}()
	entry()
}


